package com.ymy.thinking.in.spring.dependency.source;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.core.io.ResourceLoader;

import javax.annotation.PostConstruct;

/**
 * 依赖来源示例
 *
 * @author Ringo
 * @date 2021/11/23 19:57
 */
public class DependencySourceDemo {

    // 依赖注入早于 @PostConstruct 执行
    @Autowired
    private BeanFactory beanFactory;

    @Autowired
    private ResourceLoader resourceLoader;

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private ApplicationEventMulticaster applicationEventMulticaster;

    @PostConstruct
    public void init() {
        System.out.println("beanFactory = " + beanFactory);                        // DefaultListableBeanFactory
        System.out.println("resourceLoader = " + resourceLoader);                  // AnnotationConfigApplicationContext
        System.out.println("applicationContext = " + applicationContext);          // AnnotationConfigApplicationContext
        System.out.println("applicationEventMulticaster = " + applicationEventMulticaster); // SimpleApplicationEventMulticaster
    }

    @PostConstruct
    public void initByLookup() {
        getBean(BeanFactory.class);
        getBean(ResourceLoader.class);
        getBean(ApplicationContext.class);
        getBean(ApplicationEventMulticaster.class);
    }

    private <T> T getBean(Class<T> beanType) {
        try {
            return beanFactory.getBean(beanType);
        } catch (NoSuchBeanDefinitionException e) {
            System.err.println("当前类型" + beanType.getName() + "无法在 BeanFactory 中查找！");
        }
        return null;
    }

    public static void main(String[] args) {
        // IoC 容器
        AnnotationConfigApplicationContext applicationContext
                = new AnnotationConfigApplicationContext(DependencySourceDemo.class);

        // 显示关闭 Spring 应用上下文
        applicationContext.close();
    }
}
